home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: hpgl.trm%v 3.50 1993/07/09 05:35:24 woo Exp $
- */
-
- /* GNUPLOT - hpgl.trm */
- /*
- * Copyright (C) 1990
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- * This file is included by ../term.c.
- *
- * This terminal driver supports:
- * hpgl, hp7580b, HP Laserjet III
- *
- * AUTHORS
- * Colin Kelley, Thomas Williams, Russell Lang
- *
- * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
- *
- */
-
- /*
- *
- * MODIFIED for expanded HPGL/2 and PCL utilites
- * Tom Swiler (tom@silica.mse.ufl.edu)
- *
- */
-
- /*
- * The maximum plot size, in plotter units:
- */
-
- #define HPGL_PUPI 1016 /* Plotter units per inch */
-
- #define HPGL_XMAX_A 10000
- #define HPGL_YMAX_A 7500
-
- #define HPGL_XMAX_B 15200
- #define HPGL_YMAX_B 10000
-
- #define HPGL_XMAX HPGL_XMAX_A
- #define HPGL_YMAX HPGL_YMAX_A
-
- #define PCL_XMAX HPGL_XMAX_A
- #define PCL_YMAX HPGL_YMAX_A-60
-
- /*
- * Tic sizes
- */
-
- #define HPGL_VTIC (HPGL_YMAX/70)
- #define HPGL_HTIC (HPGL_YMAX/70)
-
- #define PCL_VTIC (PCL_YMAX/70)
- #define PCL_HTIC (PCL_YMAX/70)
-
- /*
- * Font size for HPGL
- */
-
- #define HPGL_VCHAR (HPGL_YMAX/100*32/10) /* 3.2% */
- #define HPGL_HCHAR (HPGL_XMAX/100*12/10) /* 1.2% */
-
- /*
- * Font size for HPGL/2
- */
-
- #define HPGL2_DEF_POINT 14 /* Height of font */
-
- #define HPGL2_DEF_PITCH (3 * 72 / (HPGL2_DEF_POINT * 2))
- #define HPGL2_VCHAR ((int) HPGL_PUPI * HPGL2_DEF_POINT / 72)
- #define HPGL2_HCHAR (HPGL2_VCHAR * 2 / 3)
-
- /*
- * Control constants
- */
-
- #define DOWN 0 /* Pen is down */
- #define UP 1 /* Pen is up */
- #define UNKNOWN -10 /* Unknown status for lots of things */
-
- /*
- * For Polyline Encoded, either use base 64 or base 32.
- * Save space with base 64, but get 8-bit characters.
- */
-
- #define HPGL2_BASE64 TRUE
-
- #if HPGL2_BASE64
- #define HPGL2_BITS 6
- #define HPGL2_LOW_OFFS 63
- #define HPGL2_HIGH_OFFS 191
- #define HPGL2_MASK 63
- #else
- #define HPGL2_BITS 5
- #define HPGL2_LOW_OFFS 63
- #define HPGL2_HIGH_OFFS 95
- #define HPGL2_MASK 31
- #endif
-
- /*
- * Data structures for options
- */
-
- struct HPGL2_font_str {
- char *compare,
- *name;
- int symbol_set,
- spacing;
- double pitch,
- height;
- int posture,
- stroke_weight,
- typeface;
- };
-
- struct PCL_mode_str {
- char *compare,
- *name,
- *command;
- int xmax,
- ymax;
- };
-
- /*
- * The default font goes first. Although it is the ugliest, the
- * stick font is probably supported by the most devices, so it
- * becomes the default.
- */
-
- static struct HPGL2_font_str GPFAR HPGL2_font_table[] = {
- {"u$nivers", "univers", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 4148},
- {"s$tick", "stick", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 48},
- {"c$g_times", "cg_times", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 4101}
- };
-
- #define HPGL2_FONTS (sizeof(HPGL2_font_table) / sizeof (struct HPGL2_font_str))
- static struct HPGL2_font_str *HPGL2_font = &HPGL2_font_table[0];
-
- /*
- * The default mode goes first. Landscape style plots are probably the
- * most compatable with other HPGL devices.
- */
-
- static struct PCL_mode_str GPFAR PCL_mode_table[] = {
- {"l$andscape", "landscape", "\033&l1O", PCL_XMAX, PCL_YMAX},
- {"p$ortrait", "portrait", "\033&l0O", PCL_YMAX, PCL_XMAX}
- };
-
- #define PCL_MODES (sizeof(PCL_mode_table) / sizeof (struct PCL_mode_str))
- static struct PCL_mode_str *PCL_mode = &PCL_mode_table[0];
-
- /*
- * Various line types and widths to distinguish data sets
- */
-
- static char *HPGL2_lt[] = {"", "4,2", "5,2", "6,2", "7,2", "8,2"},
- *HPGL2_pw[] = {".15", ".12", ".08"};
-
- #define HPGL2_LINETYPES (sizeof(HPGL2_lt) / sizeof(char *))
- #define HPGL2_PENWIDTHS (sizeof(HPGL2_pw) / sizeof(char *))
-
- /*
- * Static variables to keep track of where we are, etc.
- */
-
- static int HPGL_ang = 0,
- HPGL_x = UNKNOWN,
- HPGL_y = UNKNOWN,
- HPGL_penstate = UNKNOWN,
- HPGL_pentype = UNKNOWN,
- HPGL2_in_pe,
- HPGL2_lost;
-
- /*
- * The subroutines, grouped by function for different versions.
- */
-
- HPGL2_options ()
- {
- extern double real();
- struct termentry *t = &term_tbl[term];
- int i;
- double point_size;
- char tmp_options[MAX_ID_LEN];
- if (!END_OF_COMMAND) {
- for (i = 0; i < HPGL2_FONTS &&
- !almost_equals (c_token, HPGL2_font_table[i].compare); i++);
- if (i < HPGL2_FONTS) {
- HPGL2_font = &HPGL2_font_table[i];
- } else
- int_error ("expecting font: stick, cg_times, or univers", c_token);
- c_token++;
- if (!END_OF_COMMAND) {
- if ((point_size = real(&token[c_token].l_val)) > 0.0) {
- t->v_char = (int) HPGL_PUPI *point_size / 72;
- t->h_char = t->v_char * 2 / 3;
- if (HPGL2_font->spacing)
- HPGL2_font->height = point_size;
- else
- HPGL2_font->pitch = 72 * 3 / (point_size * 2);
- } else
- int_error ("expecting font point size: real number",c_token);
- c_token++;
- }
- }
- sprintf (tmp_options, " %s", HPGL2_font->name);
- strcat(term_options,tmp_options);
- if (HPGL2_font->spacing){
- sprintf (tmp_options, " %lf",
- HPGL2_font->height);
- strcat(term_options,tmp_options);
- }else{
- sprintf (tmp_options, " %lf",
- HPGL2_font->pitch);
- strcat(term_options,tmp_options);
- }
- }
-
- PCL_options ()
- {
- int i;
- if (!END_OF_COMMAND) {
- for (i = 0; i < PCL_MODES &&
- !almost_equals (c_token, PCL_mode_table[i].compare); i++);
- if (i < PCL_MODES)
- PCL_mode = &PCL_mode_table[i];
- else
- int_error ("expecting mode: portrait or landscape", c_token);
- c_token++;
- }
- sprintf (term_options, " %s", PCL_mode->name);
- HPGL2_options ();
- }
-
- HPGL_init ()
- {
- }
-
- HPGL2_init ()
- {
- }
-
- PCL_init ()
- {
- struct termentry *t = &term_tbl[term];
- /*
- * Reset printer, set to one copy, orientation of user's choice.
- * Make the change to the new orientation all at once.
- */
- fprintf (outfile, "\033E\033&l1X%s\n", PCL_mode->command);
- t->xmax = PCL_mode->xmax;
- t->ymax = PCL_mode->ymax;
- }
-
- HPGL_graphics()
- {
- fputs("\033.Y\n\033.I81;;17:\033.N;19:\033.M500:\n",outfile);
- /* 1
- 1. enable eavesdropping
- */
- fprintf(outfile,
- "IN;\nSC0,%d,0,%d;\nSR%f,%f;\n",
- HPGL_XMAX,HPGL_YMAX,
- ((double)(HPGL_HCHAR)*200/3/HPGL_XMAX),
- ((double)(HPGL_VCHAR)*100/2/HPGL_YMAX) );
- /* 1 2 3
- 1. reset to power-up defaults
- 2. set SCaling
- 3. set character size
- */
- HPGL_ang = 0;
- }
-
- HPGL2_graphics ()
- {
- /*
- * IN - Initialize
- * SP - Select pen
- * SD - Set default font
- */
- fprintf (outfile, "INSP1SD1,%d,2,%d,",
- HPGL2_font->symbol_set, HPGL2_font->spacing);
- if (HPGL2_font->spacing)
- fprintf (outfile, "4,%lf,", HPGL2_font->height);
- else
- fprintf (outfile, "3,%lf,", HPGL2_font->pitch);
- fprintf (outfile, "5,%d,6,%d,7,%d\n", HPGL2_font->posture,
- HPGL2_font->stroke_weight, HPGL2_font->typeface);
- /*
- * Control variables
- */
- HPGL_ang = 0; /* Horizontal */
- HPGL2_in_pe = FALSE; /* Not in PE command */
- HPGL2_lost = TRUE; /* Pen position is unknown */
- HPGL_penstate = UP; /* Pen is up */
- }
-
- PCL_graphics ()
- {
- /*
- * Enter HPGL/2 graphics mode
- */
- fputs ("\033%0B", outfile);
- HPGL2_graphics ();
- }
-
- HPGL_text ()
- {
- fputs ("PUSP0;\033.Z\n\0", outfile);
- /* 1 2 3
- 1. pen up
- 2. park pen
- 3. disable eavesdropping
- */
- HPGL_penstate = UP;
- }
-
- HPGL2_text ()
- {
- /*
- * If in Polyline Encoded command, leave Polyline Encoded command
- */
- if (HPGL2_in_pe) {
- fputs (";\n", outfile);
- HPGL2_in_pe = 0;
- }
- /*
- * Pen up, park pen
- */
- fputs ("PUSP0;", outfile);
- }
-
- PCL_text ()
- {
- if (HPGL2_in_pe) {
- fputs (";\n", outfile);
- HPGL2_in_pe = 0;
- }
- /*
- * Go into PCL mode and eject the page
- */
- fputs ("\033%1A\033&l0H\n\0", outfile);
- }
-
- HPGL_linetype (linetype)
- int linetype;
- {
- /* allow for 6 pens */
- linetype = (linetype + 2) % 6 + 1;
- /* only select pen if necessary */
- if (HPGL_pentype != linetype) {
- fprintf (outfile, "PU;\nSP%d;\n", linetype);
- HPGL_pentype = linetype;
- HPGL_penstate = UP;
- }
- }
-
- HP75_linetype (linetype)
- int linetype;
- {
- /* allow for 4 pens */
- linetype = (linetype + 2) % 4 + 1;
- /* only select pen if necessary */
- if (HPGL_pentype != linetype) {
- fprintf (outfile, "PU;\nSP%d;\n", linetype);
- HPGL_pentype = linetype;
- HPGL_penstate = UP;
- }
- }
-
- HPGL2_linetype (linetype)
- int linetype;
- {
- /*
- * If in Polyline Encoded command, leave Polyline Encoded command
- */
- if (HPGL2_in_pe) {
- fputs (";\n", outfile);
- HPGL2_in_pe = 0;
- }
- /*
- * Allow for lots of linetypes
- */
- if (linetype >= 0)
- linetype = linetype % (HPGL2_LINETYPES * HPGL2_PENWIDTHS);
- if (linetype != HPGL_pentype) {
- if (linetype >= 0) {
- fprintf (outfile, "PW%sLT%s",
- HPGL2_pw[linetype / HPGL2_LINETYPES],
- HPGL2_lt[linetype % HPGL2_LINETYPES]);
- } else if (linetype == -2)
- /*
- * Borders and tics
- */
- fprintf (outfile, "PW.2LT");
- else if (linetype == -1)
- /*
- * Axes and grids
- */
- fprintf (outfile, "PW.1LT1,.25");
- HPGL_pentype = linetype;
- }
- }
-
- HPGL_put_text (x, y, str)
- int x,
- y;
- char *str;
- {
- if (HPGL_ang == 1)
- HPGL_move (x + HPGL_VCHAR / 4, y);
- else
- HPGL_move (x, y - HPGL_VCHAR / 4);
- fprintf (outfile, "LB%s\003\n", str);
- }
-
- HPGL2_put_text (x, y, str)
- int x,
- y;
- char *str;
- {
- struct termentry *t = &term_tbl[term];
- /*
- * Position the pen
- */
- if (HPGL_ang == 1)
- HPGL2_move (x + t->v_char / 4, y);
- else
- HPGL2_move (x, y - t->v_char / 4);
- /*
- * If in Polyline Encoded command, leave Polyline Encoded command
- */
- if (HPGL2_in_pe) {
- fputs (";\n", outfile);
- HPGL2_in_pe = 0;
- }
- /*
- * Print the text string
- */
- fprintf (outfile, "LB%s\003\n", str);
- HPGL2_lost = 1;
- }
- /*
- * Some early HPGL plotters (e.g. HP7220C) require the
- * Pen Up/Down and Pen (move) Absolute commands to be separate.
- */
-
- HPGL_move (x, y)
- int x,
- y;
- {
- if (HPGL_x != x || HPGL_y != y) { /* only move if necessary */
- fprintf (outfile, "PU;PA%d,%d;\n", x, y);
- HPGL_penstate = UP;
- HPGL_x = x;
- HPGL_y = y;
- }
- }
-
- HPGL_vector (x, y)
- int x,
- y;
- {
- if (HPGL_penstate != DOWN) {
- fprintf (outfile, "PD;PA%d,%d;\n", x, y);
- HPGL_penstate = DOWN;
- } else
- fprintf (outfile, "PA%d,%d;\n", x, y);
- HPGL_x = x;
- HPGL_y = y;
- }
-
- HPGL2_move (x, y)
- int x,
- y;
- {
- register int dx,
- dy;
- if (HPGL2_in_pe) {
- dx = x - HPGL_x;
- dy = y - HPGL_y;
- fputs ("<", outfile);
- } else {
- #if HPGL2_BASE64
- fputs ("PE<", outfile);
- #else
- fputs ("PE7<", outfile);
- #endif
- if (HPGL2_lost) {
- dx = x;
- dy = y;
- HPGL2_lost = 0;
- fputs ("=", outfile);
- } else {
- dx = x - HPGL_x;
- dy = y - HPGL_y;
- }
- HPGL2_in_pe = 1;
- }
- #if HPGL2_EXPLICIT_PD
- if (HPGL_penstate == DOWN)
- HPGL_penstate = UP;
- #endif
- HPGL2_encode (dx);
- HPGL2_encode (dy);
- fputs("\n",outfile);
- HPGL_x = x;
- HPGL_y = y;
- }
-
- HPGL2_vector (x, y)
- int x,
- y;
- {
- register int dx,
- dy;
- if (HPGL2_in_pe) {
- dx = x - HPGL_x;
- dy = y - HPGL_y;
- } else {
- #if HPGL2_BASE64
- fputs ("PE", outfile);
- #else
- fputs ("PE7", outfile);
- #endif
- if (HPGL2_lost) {
- dx = x;
- dy = y;
- HPGL2_lost = 0;
- fputs ("=", outfile);
- } else {
- dx = x - HPGL_x;
- dy = y - HPGL_y;
- }
- HPGL2_in_pe = 1;
- }
- #if HPGL2_EXPLICIT_PD
- /*
- * Put the pen down in the current position,
- * relative vector of 0,0.
- */
- if (HPGL_penstate == UP) {
- fputc ((char) HPGL2_HIGH_OFFS, outfile);
- fputc ((char) HPGL2_HIGH_OFFS, outfile);
- HPGL_penstate = DOWN;
- }
- #endif
- HPGL2_encode (dx);
- HPGL2_encode (dy);
- fputs("\n",outfile);
- HPGL_x = x;
- HPGL_y = y;
- }
-
- /*
- * Routine to encode position in base 32 or base 64 characters
- */
-
- HPGL2_encode (d)
- register int d;
- {
- register int c;
- if ((d <<= 1) < 0)
- d = 1 - d;
- do {
- c = d & HPGL2_MASK;
- d >>= HPGL2_BITS;
- if (d > 0)
- fputc ((char) (c + HPGL2_LOW_OFFS), outfile);
- else
- fputc ((char) (c + HPGL2_HIGH_OFFS), outfile);
- } while (d > 0);
- }
-
- int
- HPGL_text_angle (ang)
- int ang;
- {
- HPGL_ang = ang;
- if (ang == 1)
- /*
- * Vertical
- */
- fprintf (outfile, "DI0,1;\n");
- else
- /*
- * Horizontal
- */
- fprintf (outfile, "DI1,0;\n");
- return TRUE;
- }
-
- int
- HPGL2_text_angle (ang)
- int ang;
- {
- /*
- * If in Polyline Encoded command, leave Polyline Encoded command
- */
- if (HPGL2_in_pe) {
- fputs (";", outfile);
- HPGL2_in_pe = 0;
- }
- if (ang == 1)
- /*
- * Vertical
- */
- fprintf (outfile, "DI0,1");
- else
- /*
- * Horizontal
- */
- fprintf (outfile, "DI1,0");
- HPGL_ang = ang;
- return TRUE;
- }
-
- HPGL_reset ()
- {
- /*
- * I am not sure that "PG" is a command in HPGL.
- fputs ("PG;", outfile);
- */
- }
-
- HPGL2_reset ()
- {
- /*
- * Park the pen
- * Advance a page
- * End with ";"
- */
- fputs ("SP0PG;\n", outfile);
- }
-
- PCL_reset ()
- {
- /*
- * Return to PCL mode
- * Printer reset (conditional eject)
- */
- fputs ("\033%0A\033E\n", outfile);
- }
-
- HPGL2_justify_text (just)
- int just;
- {
- /*
- * If in Polyline Encoded command, leave Polyline Encoded command
- */
- if (HPGL2_in_pe) {
- fputs (";\n", outfile);
- HPGL2_in_pe = 0;
- }
- switch (just) {
- case LEFT:
- fputs ("LO1", outfile);
- break;
- case CENTRE:
- fputs ("LO4", outfile);
- break;
- case RIGHT:
- fputs ("LO7", outfile);
- break;
- default:
- return 0;
- }
- return 1;
- }
-
-